package hotel.meituan.oversea.biz.utils;

import com.alibaba.fastjson.JSON;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.utils.DateUtil;
import hotel.base.oversea.utils.GsonUtils;
import hotel.base.oversea.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.util.ObjectUtils;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@Slf4j
public class RestTemplateUtils {

    //@Autowired
    //private RestTemplate restTemplate;//static 注入失败//再次new JobRestTemplateUtils后 restTemplate注入失败

    public static Result post(String url, String objectJsonStrParams, RestTemplate restTemplate){
        Result response = postPush(url,objectJsonStrParams,restTemplate);
        if(response.getCode() != CommonConstants.SUCCESS && null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
            log.info("Meituan RestTemplateUtils {} >>>>>>>>> {} post 接口返回失败，拦截异常失败，处理再次调用接口: {}",url, hotel.base.oversea.utils.DateUtil.getCurrTime(),response);
            //再次调用接口
            response = RestTemplateUtils.againRequestPost(3,url,objectJsonStrParams,restTemplate);
        }
        return response;
    }

    private static Result againRequestPost(int length, String url, String paramsJson, RestTemplate restTemplate){
        Result response = null;
        for (int i = 0; i < length; i++) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            log.info("Meituan RestTemplateUtils {} >>>>>>>>> {} againRequestPost 接口返回失效token或ServiceAspect异常,程序进入,三秒后重试调用接口,i={}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(),i);
            response = RestTemplateUtils.postPush(url,paramsJson,restTemplate);
            if(response.getCode()!= CommonConstants.SUCCESS){
                if(null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
                    log.info("Meituan RestTemplateUtils {} >>>>>>>>> {} againRequestPost 接口返回失效token或ServiceAspect异常,程序进入,两秒后重试调用接口,i={},{}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(),i,response);
                }else{
                    log.info("Meituan RestTemplateUtils {} >>>>>>>>> {} againRequestPost 接口返回失败: {},{}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(),response,i);
                    break;
                }
            }else{
                log.info("Meituan RestTemplateUtils {} >>>>>>>>> {} againRequestPost 接口返回成功: {},{}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(),response,i);
                break;
            }
        }
        return response;
    }

    private static Result postPush(String url, String objectJsonStrParams, RestTemplate restTemplate){
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.valueOf("application/json;UTF-8"));
        HttpEntity<String> strEntity = new HttpEntity<String>(objectJsonStrParams,headers);
        /*SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        requestFactory.setConnectTimeout(30000);// 设置超时
        requestFactory.setReadTimeout(30000);*/
        Result response = null;
        String respStr = null;
        try {
            //获取携程订单实时状态池信息
            respStr = restTemplate.postForObject(url, strEntity, String.class);
            if(ObjectUtils.isEmpty(respStr)){
                return new Result<>("Meituan RestTemplateUtils postPush 接口异常返回null",-1);
            }
            if(respStr.contains("code")){
                response = GsonUtils.GsonToBean(respStr,Result.class);
            }else{
                Result result = new Result();
                result.setCode(-1);
                result.setMsg(respStr);
                return result;
            }
        } catch (Exception e) {
            response = new Result();
            response.setCode(-1);
            String msg = DateUtil.getNowTime()+" 发起POST请求异常 "+e.getMessage()+",url = "+url+",strEntity = "+strEntity+",respStr="+respStr;
            response.setMsg(msg);
            log.error("Switchs RestTemplate postPush {}",msg);
            log.error(e.getMessage(), e);
        }
        if(null == response){
            return new Result<>("Meituan RestTemplateUtils postPush 接口异常返回null",-1);
        }
        return response;
    }

    public static void main(String[] args) {

        Map map = GsonUtils.GsonToMaps("{\n" +
                "    \"code\": 200,\n" +
                "    \"msg\": \"success\",\n" +
                "    \"data\": {\n" +
                "        \"goodsId\": 24481864,\n" +
                "        \"roomId\": 162891922,\n" +
                "        \"remain\": 0\n" +
                "    }\n" +
                "}");
        Result response = new Result();
        if(null != map.get("code")){
            response = GsonUtils.GsonToBean("{\n" +
                    "    \"code\": 200,\n" +
                    "    \"msg\": \"success\",\n" +
                    "    \"data\": {\n" +
                    "        \"goodsId\": 24481864,\n" +
                    "        \"roomId\": 162891922,\n" +
                    "        \"remain\": 0\n" +
                    "    }\n" +
                    "}",Result.class);
        }
        System.out.printf("g:"+ JSON.toJSONString(response));
    }

    public static Result get(String url, Map<String, Object> paramsValuesMap, RestTemplate restTemplate){
        /*if(null == paramsValuesMap || paramsValuesMap.size()==0){
            return new Result<>("paramsValuesMap 不可为空 至少存在 access_token",CommonConstants.REQUEST_ERROR);
        }*/
        Result response = getPush(url,paramsValuesMap,restTemplate);

        if(null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
            log.info("Meituan RestTemplateUtils {} >>>>>>>>> {} get 接口返回失败，拦截异常失败，处理再次调用接口: {}",url, hotel.base.oversea.utils.DateUtil.getCurrTime(),response);
            //再次调用接口
            return RestTemplateUtils.againRequestGet(3,url,paramsValuesMap,restTemplate);
        }else{
            return response;
        }


    }

    private static Result againRequestGet(int length, String url, Map<String, Object> paramsValuesMap, RestTemplate restTemplate){
        Result response = null;
        for (int i = 0; i < length; i++) {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            log.info("Meituan RestTemplateUtils{} >>>>>>>>> {} againRequestPost 接口返回失效token或ServiceAspect异常,程序进入,token失效重试调用接口,i={}，paramsJson={}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(), JSON.toJSONString(paramsValuesMap));
            response = RestTemplateUtils.postPush(url, JSON.toJSONString(paramsValuesMap),restTemplate);
            if(response.getCode()!= CommonConstants.SUCCESS){
                if(null != response.getMsg() && (response.getMsg().toString().contains("token") || response.getMsg().toString().contains("ServiceAspect"))){
                    //if(null != response.getMsg() && (response.getMsg().toString().contains("token"))){
                    log.info("Meituan RestTemplateUtils{} >>>>>>>>> {} againRequestPost 接口返回失效token或ServiceAspect异常,程序进入,再次token失效重试调用接口,i={},response={},paramsJson={}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(),i, JSON.toJSONString(response), JSON.toJSONString(paramsValuesMap));
                }else{
                    log.info("Meituan RestTemplateUtils{} >>>>>>>>> {} againRequestPost 接口返回失败: response={},i={},paramsJson={}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(), JSON.toJSONString(response),i, JSON.toJSONString(paramsValuesMap));
                    break;
                }
            }else{
                log.info("Meituan RestTemplateUtils{} >>>>>>>>> {} againRequestPost 接口返回成功: {},{}", url,hotel.base.oversea.utils.DateUtil.getCurrTime(),response,i);
                break;
            }
        }
        return response;
    }

    private static Result getPush(String url, Map<String, Object> paramsValuesMap, RestTemplate restTemplate){
        //发起请求
        String responseStr = null;
        String sendUrl = null;
        if(null != paramsValuesMap && paramsValuesMap.size()>0){
            String paramsFormatStr = "?";//"?access_token={access_token}&countryID={countryID}&currentPageIndex={currentPageIndex}&pageSize={pageSize}";
            for (Map.Entry<String, Object> enrty:paramsValuesMap.entrySet()){
                paramsFormatStr += enrty.getKey()+"="+"{"+enrty.getKey()+"}&";
            }
            if(!paramsFormatStr.equals("?")){
                paramsFormatStr  = paramsFormatStr.substring(0,paramsFormatStr.length()-1);
            }
            sendUrl = url +paramsFormatStr;
        }else{
            sendUrl = url;
        }

        try {
            if(null != paramsValuesMap && paramsValuesMap.size()>0){
                responseStr = restTemplate.getForObject(sendUrl , String.class,paramsValuesMap);
            }else{
                responseStr = restTemplate.getForObject(sendUrl , String.class);
            }

        }catch (Exception e){
            Result response = new Result();
            response.setCode(-1);
            String msg = DateUtil.getCurrTime()+" 发起GET请求异常,url = "+sendUrl+"  paramsValuesMap = "+ JSON.toJSONString(paramsValuesMap)+","+e.getMessage();
            response.setMsg(msg);
            log.error("JobRestTemplate getPush {}",msg);
            log.error(e.getMessage(), e);
        }
        if(ObjectUtils.isEmpty(responseStr)){
            return new Result<>("Meituan RestTemplateUtils getPush 接口异常返回null，请求参数："+ JSON.toJSONString(paramsValuesMap),-1);
        }
        Result response = null;
        try{

            if(responseStr.contains("code")){
                response = GsonUtils.GsonToBean(responseStr,Result.class);
            }else{
                Result result = new Result();
                result.setCode(-1);
                result.setMsg(responseStr);
                return result;
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
            return new Result<>("getPush 转化接口返回异常:"+response+"  |  "+e.getMessage(),-1);
        }
        return response;
    }

}
